#import "MatrixSet.h"
#import "ColumnMatrix.h"
#import "instr.h"
#import "regexpr.h"
#import "Article.h"

@implementation MatrixSet

- init
{
   [super init];
   currentSelection=nil;
   numSelCells=0;
   return self;
}

- theMatrix
{
   return myMatrix;
}

- (List *)matrixList
{
   return myMList;
}

- (int)numSelCells
{
   return numSelCells;
}

- redisplayMatrix
{
   [myMatrix display];
   return self;
}

- currentSelection
{
   return currentSelection;
}



- sync
{
   [self syncAndReturnList:NO];
   return self;
}

- syncAndReturnList:(BOOL)flag
{
   List *selectionList=[myMatrix getCurrSelections];
   int oldNumSelCells=numSelCells;

   numSelCells=[selectionList count];
   if(numSelCells==1)
      currentSelection=[selectionList objectAt:0];
   else
      currentSelection=nil;

   if((oldNumSelCells==1)&&(numSelCells!=1))
      [unselTarget perform:unselAction];

   if(flag==FALSE){
      [selectionList free];
      return self;
   }
 
   return selectionList; 
}

- (const char *)stringValueForCellAt:(int)index
{
   return [[myMList objectAt:index] stringValue];
}

- (int)grep:(const char *)pattern regexpr:(BOOL)regexpr cases:(BOOL)cases
{
   int i,j;
   List *selList;
   unsigned char fm[256], tr[256];
   struct re_pattern_buffer rpat;

   selList=[[List alloc] init];
   j=[myMList count];
   if(j==0)
      return 0;

   if(regexpr){
      char *str;
      memset(&rpat, 0, sizeof(rpat));
      for(i=256; i--;)
         tr[i] = i;
      if(!cases)
         for(i='A'; i<='Z'; i++) tr[i] = i-'A'+'a';
      rpat.translate = tr; rpat.fastmap = fm;
      str = re_compile_pattern((char *)pattern,strlen(pattern), &rpat);
      if (str!=NULL)
        return (strcmp(str, "Out of memory")?SEARCH_INVALID_REGEXPR:SEARCH_INTERNAL_ERROR);
   }

   for(i=0;i<j;i++){
      const char *cellString=[self stringValueForCellAt:i];
      BOOL found=FALSE;

      if(regexpr){
        int l=strlen(cellString);
        int p=re_search_pattern(&rpat,(char *)cellString,l,0,l,0);

        if(p==-2)
           return SEARCH_INTERNAL_ERROR;
        found= (p==-1)? FALSE : TRUE;
      }
      else
         found=(instr(cellString,pattern,cases)!=NULL);

      if(found)
         [selList addObject:[myMList objectAt:i]];
   }

   j=[selList count];
   if(j>0){
      [myMList makeObjectsPerform:@selector(unsetTag)];
      [selList makeObjectsPerform:@selector(setTag)];
      for(i=0;i<j;i++)
         if([[selList objectAt:i] isTaged]){
            [[myMatrix reloadMatrix] display];
            [self sync];
            break;
         }
      if(i==j) j=0; //articles may be killed
   }
   [selList free];

   return j;
}

@end
